#include "DataStructureH/queue.h"
#include <_mingw_mac.h>

template <typename T> Queue<T>::Queue() : Head(nullptr), Tail(nullptr)
{

}
template <typename T> Queue<T>::Queue(T *item_ptr)
{
    Enqueue(item_ptr);
}
template <typename T> Queue<T>::~Queue()
{
    auto it{Tail}, t{it};
    while(!isEmpty() && !Tail)
    {
        it = it->back;
        delete t;
        t = it;
    }
}
template <typename T> inline void _NewNode(QNode<T> *&ptrNode, T *&ptrItem, QNode<T> *&ptrBack = nullptr)
{
    ptrNode = new QNode<T>;
    ptrNode->data = ptrItem;
    ptrNode->back = ptrBack;
}
template <typename T> Action_t Queue<T>::Enqueue(T *item_ptr)
{
    if (!item_ptr)
        return -1;

    if (Tail == nullptr)
        _NewNode(Tail, item_ptr, nullptr);
    else
        {_NewNode(Head->back, item_ptr, nullptr);
        Head = Head->back;}
    return 1;
}
template <typename T> Action_t Queue<T>::Enqueue(const T &item)
{
    T *newItem = new T(item);
    return Enqueue(newItem);
}

template <typename T> Action_t Queue<T>::Dequeue(T *ret_item)
{
    if (!ret_item || isEmpty())
        return -1;
    ret_item = Tail; 
    auto t = Tail;
    Tail = Tail->back;
    delete t;
    return 1;
}
template <typename T> T& Queue<T>::Dequeue() const
{
    if(isEmpty()) return -1;
    auto t = Tail;
    auto tData = t->data;
    Tail = Tail->back;
    delete t;
    return *tData;
}

template <typename T> int Queue<T>::getcount() const
{
    return count;
}

template <typename T> bool Queue<T>::isEmpty() const
{
    return (Tail == nullptr);
}

template <typename T> T& Queue<T>::getHead()
{
    return *Head->data;
}

template <typename T> T &Queue<T>::getTail()
{
    return *Tail->data;
}
